package com.weiyuwqj.server.service.invest.module;

import com.weiyuwqj.api.constant.Constants;
import com.weiyuwqj.api.constant.DealType;
import com.weiyuwqj.api.constant.Global;
import com.weiyuwqj.api.constant.Message;
import com.weiyuwqj.api.constant.OperateContants;
import com.weiyuwqj.api.exception.CrowdException;
import com.weiyuwqj.api.model.*;
import com.weiyuwqj.api.model.vo.DebtCollectStatVo;
import com.weiyuwqj.api.service.BasDebtService;
import com.weiyuwqj.api.util.DateUtils;
import com.weiyuwqj.api.util.IpUtils;
import com.weiyuwqj.api.util.RandomCodesUtils;
import com.weiyuwqj.server.mapper.*;
import com.weiyuwqj.server.service.account.module.DealAction;
import com.weiyuwqj.server.service.account.module.DealModule;
import com.weiyuwqj.server.service.account.module.action.sys.GiveCouponDealAction;
import com.weiyuwqj.server.service.account.module.action.user.invest.InvestDealAction;
import com.weiyuwqj.server.service.account.module.action.user.invest.UseCouponDealAction;
import com.weiyuwqj.server.service.finance.module.OperateModule;
import com.weiyuwqj.server.service.finance.module.action.ExpendOperateAction;
import com.weiyuwqj.server.service.finance.module.action.OperateAction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by huzj on 2017/3/22.
 */
@Component
public class DebtInvestModule {
    @Autowired
    private BasDebtMapper debtMapper;

    @Autowired
    private BusAccountMapper accountMapper;

    @Autowired
    private BasCouponMapper basCouponMapper;

    @Autowired
    private BusItemCollectMapper itemCollectMapper;

    @Autowired
    private BusDebtCollectMapper debtCollectMapper;

    @Autowired
    private BusDebtInvestMapper debtInvestMapper;

    @Autowired
    private DealModule dealModule;

    @Autowired
    private BasItemMapper itemMapper;

    @Autowired
    private BusBonusRebateMapper bonusRebateMapper;

    @Autowired
    private BusUserStatMapper userStatMapper;

    @Autowired
    private OperateModule operateModule;

    public Map doInvest(Integer userId, BigDecimal amount, BasDebt debt, Integer couponId, Integer investType) {

        //判断项目是否存在
        if (debt == null) {
            throw new CrowdException("debt.not_exist");
        }

        BigDecimal totalAmount = debt.getAmount();
        BigDecimal onGoingAmount = debt.getOngoingAmount();
        BigDecimal remainAmount = totalAmount.subtract(onGoingAmount);
        BigDecimal couponAmount = BigDecimal.ZERO;
        BigDecimal investAmount = amount;
        BigDecimal remainCollectAmount = BigDecimal.ZERO;
        BigDecimal remainCollectPrincipal = BigDecimal.ZERO;
        BigDecimal remainCollectInterest = BigDecimal.ZERO;
        BigDecimal interest = BigDecimal.ZERO;


        //判断用户登录状态
        if (null == userId || userId < 1) {
            throw new CrowdException("item.invest.session_out");
        }

        //查看投资金额是否是整数
        if (new BigDecimal(amount.intValue()).compareTo(amount) != 0) {
            throw new CrowdException("debt.invest.amount_not_a_integer");
        }

        //判断债权是否已债转
        if (debt.getStatus() != 0) {
            throw new CrowdException("debt.has_full");
        }

        //判断债权是否过期
        Date endTime = DateUtils.addDays(debt.getAddtime(), debt.getEndDays());
        if (endTime.getTime() < new Date().getTime()) {
            throw new CrowdException("debt_had_expired");
        }

        //判断发布者的类型
        if (amount.compareTo(BigDecimal.ZERO) < 0) {
            throw new CrowdException("debt.invest_mount_must_more_than_zero");
        } else if (debt.getType() == 1 && amount.compareTo(totalAmount) != 0) {
            throw new CrowdException("debt.personal.amount_limit");
        } else if (debt.getType() == 2
                && remainAmount.compareTo(Constants.DEBT_LOWEST_AMOUNT) > 0
                && amount.compareTo(Constants.DEBT_LOWEST_AMOUNT) < 0) {
            throw new CrowdException("debt.company.amount_limit");
        } else if (remainAmount.compareTo(BigDecimal.ZERO) <= 0) {
            throw new CrowdException("debt_has_no_more_money");
        }

        //查看是否使用红包
        BasCoupon coupon = null;
        if (null != couponId && couponId > 0) {
            coupon = basCouponMapper.selectByPrimaryKey(couponId);
            if (null != coupon) {
                couponAmount = coupon.getAmount();
                investAmount = investAmount.subtract(couponAmount);
            }
            if (coupon.getRequireAmount().compareTo(investAmount) > 0) {
                throw new CrowdException("debt.invest.coupon.require_amount_not_meet");
            }
        }

        //判断用户可用余额
        BusAccount account = accountMapper.getBusAccountByUserId(userId);
        BigDecimal accountCash = account.getCash();
        BigDecimal accountUsable = account.getUsable();
        if (accountCash.compareTo(investAmount) < 0 || accountUsable.compareTo(investAmount) < 0) {
            throw new CrowdException("account_has_no_more_money");
        }

        //计算用户待收金额
        DebtCollectStatVo totalCollectStat;
        DebtCollectStatVo personalCollect = new DebtCollectStatVo();
        Map param = new HashMap();
        param.put("collectUserId", debt.getUserId());
        BigDecimal investProportion = amount.divide(totalAmount, 6, BigDecimal.ROUND_DOWN);
        if (debt.getDebtInvestId() != null && debt.getDebtInvestId() > 0) {
            param.put("investId", debt.getDebtInvestId());
            totalCollectStat = debtCollectMapper.statNoPayCollect(param);
        } else {
            param.put("investId", debt.getInvestId());
            totalCollectStat = itemCollectMapper.statNoPayCollect(param);
        }
        personalCollect.setCollectAmount(totalCollectStat.getCollectAmount().multiply(investProportion));
        personalCollect.setCollectPrincipal(totalCollectStat.getCollectPrincipal().multiply(investProportion));
        personalCollect.setCollectInterest(totalCollectStat.getCollectInterest().multiply(investProportion));


        //更新债转项目状态
        BigDecimal newOnGoingAmount = onGoingAmount.add(amount);
        BigDecimal debtScale;
        if (newOnGoingAmount.compareTo(totalAmount) < 0) {
            debtScale = newOnGoingAmount.multiply(new BigDecimal(100)).
                    divide(totalAmount, 2, BigDecimal.ROUND_DOWN);
            debt.setOngoingAmount(newOnGoingAmount);
            debt.setDebtScale(debtScale);
        } else {
            debtScale = new BigDecimal(100);
            debtMapper.updateDebtStatus(0, 1, debt.getId());
            Map map = new HashMap();
            map.put("fullTime", new Date());
            map.put("debtId", debt.getId());
            debtMapper.updateFullTime(map);
        }

        //更新债转项目金额和进度
        int count = debtMapper.updateAmountAndScale(amount, onGoingAmount, debtScale, debt.getId());
        if (count < 1) {
            throw new CrowdException("debt.invest.busy");
        }

        //插入债转投资记录
        String investOrder = RandomCodesUtils.getOrderNo();
        BusDebtInvest debtInvest = new BusDebtInvest();
        debtInvest.setDebtId(debt.getId());
        debtInvest.setDebtUserId(debt.getUserId());
        debtInvest.setDebtInvestId(debt.getDebtInvestId());
        debtInvest.setItemId(debt.getItemId());
        debtInvest.setInvestUserId(userId);
        debtInvest.setInvestId(debt.getInvestId());
        debtInvest.setInvestType(investType);
        debtInvest.setInvestOrder(investOrder);
        debtInvest.setStatus(0);
        debtInvest.setInvestAmount(amount);
        debtInvest.setCollectAmount(remainCollectAmount);
        debtInvest.setCollectPrincipal(remainCollectPrincipal);
        debtInvest.setCollectInterest(remainCollectInterest);
        debtInvest.setInterest(interest);
        debtInvest.setAddtime(new Date());
        debtInvest.setUpdatetime(new Date());
        debtInvest.setAddip(IpUtils.get());
        debtInvest.setCollectAmount(personalCollect.getCollectAmount());
        debtInvest.setCollectPrincipal(amount);
        debtInvest.setCollectInterest(personalCollect.getCollectInterest());
        debtInvestMapper.insertDebtInvest(debtInvest);

        //操作平台账户金额和红包状态
        BasItem item = itemMapper.selectByPrimaryKey(debt.getItemId());
        String remark = item.getItemName() + "投资" + investAmount;
        if (null != couponId && couponId > 0 && null != coupon) {
            if (coupon.getRequireAmount().compareTo(investAmount) > 0) {
                throw new CrowdException("debt.invest.coupon.require_amount_not_meet");
            }

            //更新红包状态
            Map couponMap = new HashMap();
            couponMap.put("debtInvestId", debtInvest.getId());
            couponMap.put("investId", 0);
            couponMap.put("useTime", new Date());
            couponMap.put("userId", userId);
            couponMap.put("id", couponId);
            couponMap.put("newStatus", 1);
            couponMap.put("oldStatus", 2);
            count = basCouponMapper.updateCouponStatus(couponMap);
            if (count < 1) {
                throw new CrowdException("invest.coupon_status_update_error");
            }
            couponMap.clear();
            couponMap.put("userId", userId);
            couponMap.put("couponAmount", coupon.getAmount());
            userStatMapper.updateCoupon(couponMap);
            remark = remark + "元,红包" + couponAmount + "元";

            //平台账户扣款
            DealAction giveCouponDealAction = new GiveCouponDealAction();
            giveCouponDealAction.deal(
                    Integer.parseInt(Global.getExperienceGoldAccountId()),
                    coupon.getAmount(), item.getItemName() + "发放红包扣款");
            count = dealModule.dealAction(giveCouponDealAction);
            if (count < 1) {
                throw new CrowdException("debt.invest.busy");
            }

            //插入返利收费红包表
            BusBonusRebate bonusRebate = new BusBonusRebate();
            bonusRebate.setPayUserId(Integer.parseInt(Global.getExperienceGoldAccountId()));
            bonusRebate.setReceiveUserId(userId);
            bonusRebate.setStatus(1);
            bonusRebate.setOrderNo(investOrder  );
            bonusRebate.setAmount(coupon.getAmount());
            bonusRebate.setOperType(DealType.INVEST);
            bonusRebate.setAddtime(new Date());
            bonusRebate.setRemark(remark);
            bonusRebateMapper.insert(bonusRebate);

            //投资人增加红包待收资金
            DealAction couponAction = new UseCouponDealAction();
            couponAction.deal(userId, coupon.getAmount(), "使用红包");
            dealModule.dealAction(couponAction);
        }

        //统计投资
        Map investMap = new HashMap();
        investMap.put("userId", userId);
        investMap.put("investAmount", investAmount);
        userStatMapper.updateInvest(investMap);

        //操作用户金额
        DealAction action = new InvestDealAction();
        action.deal(userId, amount, remark);
        count = dealModule.dealAction(action);
        if (count < 1) {
            throw new CrowdException("debt.invest.busy");
        }
        OperateAction operate = new ExpendOperateAction();
        operate.operateAction(investOrder, OperateContants.INVESTORS_INVEST,debt.getItemId(),
                item.getItemName(),amount);
        operateModule.operateAction(operate);

        Map map = new HashMap();
        map.put("result", "success");
        map.put("debtScale", debtScale);
        map.put("debtInvestId", debtInvest.getId());
        return map;
    }
}

